home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Graphic Gems I, II & III (C_C++) / Graphics Gems C Code.sea / GemsIII / fastLinear.c < prev    next >
Text File  |  1992-06-16  |  5KB  |  125 lines

  1. /****************************************************************************
  2.   FAST LINEAR COLOR RENDERER
  3.   Russell C.H. Cheng, University of Wales,  Cardiff 21 Jan 1992
  4.  
  5.   The renderer assumes true 24-bit color with a linear memory frame-buffer
  6.   of 4-byte integers, lowest byte is r, then g, then b, with the top byte
  7.   not used.
  8.  
  9.   The renderer precalculates and stores the merged 24-bit rgb x-offsets.
  10.   This avoids a separate interpolation for each of the r, g and b variables
  11.   for every pixel.
  12.  
  13.   Entry:
  14.   For clarity the required input variables are passed to the renderer
  15.   as arguments, Details of each variable are given in the listing.  In a
  16.   general program it will be more compact to hold these variables in a
  17.   structure and pass a pointer to this.
  18.  
  19.   Exit:
  20.   The renderer outputs directly to the designated frame-buffer.
  21. ****************************************************************************/
  22.  
  23. #define HRES 768  /*  horizontal resolution, adjust this as necessary */
  24. #define VRES 512  /*  vertical resolution, adjust this as necessary   */
  25.  
  26. void FastLinearRend( xmin,xmax,ymin,ymax, xleft,xright, r0,g0,b0,z0, x0,y0,
  27.              dr_by_dx, dr_by_dy, dg_by_dx, dg_by_dy, db_by_dx, db_by_dy,
  28.              dz_by_dx, dz_by_dy, screen_buffer_ptr, z_buffer_ptr)
  29.  
  30. int xmin,     /*  The extent of the polygon being rendered:                 */
  31.     xmax,     /*  xmin and xmax give the x-values of the leftmost and       */
  32.     ymin,     /*  rightmost pixels of the polygon, and ymin and ymax the    */
  33.     ymax;     /*  largest and smallest y-values encountered in the polygon  */
  34.  
  35. int * xleft,   /* Pointers to arrays holding the x-value of the leftmost    */
  36.     * xright;  /* and rightmost pixel occupied by the polygon on each       */
  37.                /* scanline. The values xleft[ymin],..., xleft[ymax], and    */
  38.                /* xright[ymin],..., xright[ymax] should all be set on entry */
  39.                /* The arrays themselves in the main program should be each  */
  40.                /* of size VRES                                              */
  41.  
  42. float r0,g0,b0; /* Base rgb values of the polygon at the pixel position     */
  43.                 /* x0, y0; each in the range 0.0 - 255.0 */
  44.  
  45. float z0;       /* Base z-distance of the polygon at pixel position x0, y0  */
  46.  
  47. int x0,y0;      /* Position of base pixel, this need not be a pixel of the */
  48.                 /* polygon, but is typically a vertex or the origin (0,0)  */
  49.  
  50. float  dr_by_dx, dr_by_dy,   /*  r, g, b color and       */
  51.        dg_by_dx, dg_by_dy,   /*  z-distance increments   */
  52.        db_by_dx, db_by_dy,   /*  in the x and y          */
  53.        dz_by_dx, dz_by_dy;   /*  directions              */
  54.   
  55. int *  screen_buffer_ptr;    /* Pointer to the frame buffer base address   */
  56.                              /* The frame buffer is assumed to be linear   */
  57.                              /* memory, comprising VRES horizontal lines   */
  58.                              /* with HRES pixels per line                  */
  59.  
  60. float *  z_buffer_ptr;       /* Pointer to the z-buffer base address */
  61.                              /* The buffer-size is HRES*VRES         */
  62.  
  63. {
  64.       float r,g,b,z,         /* current r g b z values */
  65.             r1,g1,b1,z1;     /* r g b z values at position x0, y */
  66.  
  67.       float dx,dy;           /* offsets of current pixel position */
  68.                              /* from that of base pixel           */
  69.  
  70.       int x,y;               /* current pixel position            */
  71.  
  72.       int *  screen_buffer;  /* pointer to current frame-buffer position  */
  73.       float *  z_buffer;     /* pointer to current z-buffer position      */
  74.  
  75.       int col;               /*  This holds the 24-bit rgb color of the */
  76.                              /*  leftmost pixel of the current scanline */
  77.  
  78.       int rgboffset[HRES];   /*  This array holds the merged     */
  79.                              /*  24-bit rgb x-direction offsets  */
  80.  
  81.       /* find r1, g1, b1, z1, the rgbz value at (x0,ymin) */
  82.       dy = (ymin - y0);
  83.       r1 = r0 + dr_by_dy * dy;
  84.       g1 = g0 + dg_by_dy * dy;
  85.       b1 = b0 + db_by_dy * dy;
  86.       z1 = z0 + dz_by_dy * dy;
  87.  
  88.       /* find the merged 24-bit rgb x-offset values along a scanline  */
  89.       for (x = xmin; x <= xmax; x++) {
  90.           dx = (x - x0);
  91.           r = dr_by_dx * dx;
  92.           g = dg_by_dx * dx;
  93.           b = db_by_dx * dx;
  94.           rgboffset[x] = ((int)r) + (((int)g)<<8) + (((int)b)<<16);
  95.       }
  96.     
  97.       /* now go through each scanline */
  98.       for (y = ymin; y<= ymax; y++)  {
  99.           /* for each scanline, find the 24-bit color value at (x0,y) */
  100.           col = ((int)r1) + (((int)g1)<<8) + (((int)b1)<<16);
  101.  
  102.           /* and find the z value at (xleft[y],y) */
  103.           dx  = xleft[y] - x0;
  104.           z   = z1 + dz_by_dx * dx;
  105.  
  106.           /* then render the scanline */
  107.           screen_buffer = screen_buffer_ptr + y*HRES;
  108.           z_buffer = z_buffer_ptr + y*HRES;
  109.           for (x = xleft[y]; x<=xright[y]; x++) {
  110.               if ( z < z_buffer[x] ) {
  111.                    screen_buffer[x] = col + rgboffset[x];
  112.                    z_buffer[x] = z;
  113.               }
  114.               z += dz_by_dx;
  115.           }
  116.  
  117.           /* and increment the r1 g1 b1 z1 value ready for the next y */
  118.           r1 += dr_by_dy;
  119.           g1 += dg_by_dy;
  120.           b1 += db_by_dy;
  121.           z1 += dz_by_dy;
  122.       }
  123.  
  124. }
  125.